package com.dpiinc.TechPage.video

import android.annotation.SuppressLint
import android.content.Context
import android.graphics.*
import android.os.Handler
import android.util.Log
import com.dpiinc.TechPage.widget.CirclePgBar
import com.dpiinc.TechPage.widget.VideoProgressView
import com.beiji.lib.pen.constants.PaletteColor
import com.beiji.lib.pen.constants.PaperSize
import com.beiji.lib.pen.model.PenStroke
import com.beiji.lib.pen.model.PenStroke.Companion.ACTION_ERASER
import com.beiji.lib.pen.screenDensity
import java.text.SimpleDateFormat
import java.util.*
import kotlin.collections.ArrayList
import java.math.BigDecimal
import com.beiji.lib.pen.model.PenStroke.Companion.ACTION_MARK
import com.beiji.lib.pen.model.PenStroke.Companion.ACTION_STROKE
import android.graphics.Bitmap
import com.dpiinc.TechPage.R
import android.view.LayoutInflater
import com.dpiinc.TechPage.user.utils.ViewToBitmapUtil.loadBitmapFromView
import android.graphics.BitmapFactory
import android.util.SparseArray
import com.dpiinc.TechPage.AIWriteApplication
import com.dpiinc.TechPage.user.utils.ViewToBitmapUtil
import com.beiji.lib.pen.device.PenT111
import java.io.*

@Suppress("UNREACHABLE_CODE")
class StrokeToBitmap {
    val TAG = "StrokeToBitmap"
//    val path = Environment.getExternalStorageDirectory().absolutePath + "/aiwirtetemp/"
    val path = AIWriteApplication.instance?.getExternalFilesDir("aiwirte")?.absolutePath + "/aiwirtetemp/"
//    val path = AIWriteApplication.instance().externalCacheDir!!.absolutePath + "/aiwirtetemp/"

    var paperSize = PaperSize.A5
    var width: Int = 0
    var VideoPath: String? = null
    var isChange: Boolean = false
    var progress: Double = 0.0
    var pagesize = 1
    private var handler: Handler? = null
    lateinit var circlePgBar: CirclePgBar
    var index: Double = 0.0
    var mcontext: Context? = null

    //画布宽度
    var bgWidth: Int = 0

    //画布高度
    var bgHeight: Int = 0

    companion object {
        @SuppressLint("StaticFieldLeak")
        @JvmStatic
        val instance = StrokeToBitmap()
    }

    fun getPaint(context: Context): Paint {
        val paint = Paint()
        paint.isAntiAlias = true
        paint.strokeWidth = 1f
        paint.style = Paint.Style.STROKE
        paint.strokeJoin = Paint.Join.ROUND
        paint.strokeCap = Paint.Cap.ROUND
        paint.strokeMiter = 0.3f
        return paint
    }

    fun getMarkPaint(context: Context, color: PaletteColor): Paint {
        val p = Paint()
        p.strokeWidth = 1f * 8
        p.style = Paint.Style.STROKE
        p.strokeJoin = Paint.Join.ROUND
        p.strokeCap = Paint.Cap.ROUND
        p.strokeMiter = 0.3f
        p.isAntiAlias = true
        p.color = color.toColor()
        p.alpha = 63
//        p.xfermode = PorterDuffXfermode(PorterDuff.Mode.DST_OVER)
        return p
    }

    var currBookId = -1
    var currHeight = -1
    fun drawStrokesTenSecond(strokeList: ArrayList<PenStroke>, context: Context, circlePgBar: CirclePgBar, wit: Int) {
        bgWidth = context.resources.displayMetrics.widthPixels
        this.circlePgBar = circlePgBar
        handler = Handler()
        mcontext = context
        width = 600
        isChange = true
//        val baseBitmap = Bitmap.createBitmap(width, getBoardHeight(), Bitmap.Config.ARGB_4444)
//        val canvas = Canvas(baseBitmap)
//        var baseBitmap: Bitmap? = null
//        val canvas = Canvas()
        val clearPaint = Paint().apply {
            xfermode = PorterDuffXfermode(PorterDuff.Mode.CLEAR)
        }

        progress = 0.0

        var allPoint = 0
        var markpoint = 0
        var strokpoint = 0
        var eraserpoint = 0
        var curIndex: Double = 0.0

        var amark = 0
        var astroke = 0

        Thread(Runnable {
            var baseBitmap: Bitmap? = null
            var canvas: Canvas = Canvas()
            circlePgBar.setmProgress(progress)
            Log.i(TAG, "progress -> $progress")
            var bitmaplist: ArrayList<ByteArray> = mutableListOf<ByteArray>() as ArrayList<ByteArray>
            Log.e(TAG, "$allPoint")

            for (k in strokeList.indices) {
                allPoint += strokeList[k].list.size
                when {
                    strokeList[k].action == PenStroke.ACTION_STROKE -> strokpoint += strokeList[k].list.size
                    strokeList[k].action == PenStroke.ACTION_MARK -> markpoint += strokeList[k].list.size
                    strokeList[k].action == PenStroke.ACTION_ERASER -> eraserpoint += strokeList[k].list.size
                }
            }
            val pageList = ArrayList<Int>()
            var pageMap: SparseArray<TempPageMap> = SparseArray()

            strokeList.forEach {
                if (pageMap.indexOfKey(it.bookId * 10000 + it.page) < 0) {
                    pageList.add(it.bookId * 10000 + it.page)
                    pageMap.append((it.bookId * 10000 + it.page), TempPageMap(it.page, it.bookId))
                }
            }
            val pageSize = pageList.size
            Log.e(TAG, "$pageSize")
            progress = 0.0
            circlePgBar.setmProgress(progress)
            Log.i(TAG, "progress -> $progress")
            for (i in 0 until pageSize) {
                val page = pageMap[pageList[i]].page
                val bookId = pageMap[pageList[i]].bookId
                if (bookId != currBookId) {
                    currBookId = bookId
                    bgHeight = PenT111.instance.calculatedHeight(currBookId, bgWidth)
                    currHeight = PenT111.instance.calculatedHeight(currBookId, this.width)
                    baseBitmap = Bitmap.createBitmap(width, currHeight, Bitmap.Config.ARGB_4444)
                    canvas.setBitmap(baseBitmap)
                }
                val tempList: ArrayList<PenStroke> = mutableListOf<PenStroke>() as ArrayList<PenStroke>
                var n = 0
                var strokeCount = 0
                while (n < strokeList.size) {
                    if (strokeList[n].page == page && strokeList[n].bookId == bookId) {
                        tempList.add(strokeList[n])
                        strokeCount += strokeList[n].list.size
                        strokeList.removeAt(n)
                    } else {
                        n++
                    }
                }
                if (tempList.size == 0) {
                    continue
                } else {
                    Log.i(TAG, "draw page -> $page")
                    for (k in tempList.indices) {
                        if (tempList[k].action == ACTION_ERASER) {
                            val eraserStroke = tempList[k]
                            val peraser = Paint()
                            peraser.color = Color.WHITE
                            for (j in 0 until eraserStroke.list.size) {
                                val float = eraserStroke.list[j].f * context.screenDensity / 2 / wit * 600
                                canvas?.drawCircle(getX(eraserStroke.list[j].x), getY(eraserStroke.list[j].y), float, peraser)
                                if (j == 0 || j == eraserStroke.list.size - 1) {
//                                    bitmaplist = bitmapListOom(bitmaplist, ImageDispose.Bitmap2Bytes(baseBitmap.copy(Bitmap.Config.ARGB_4444, false)))
                                    bitmaplist = bitmapListOom(bitmaplist, ImageDispose.Bitmap2Bytes(baseBitmap))
                                }
                            }
                        } else if (tempList[k].action == ACTION_MARK) {
                            val markStroke = tempList[k]
                            val p = getMarkPaint(context, PaletteColor.fromId(markStroke.color))
                            p.alpha = 63
                            p.strokeWidth = context.screenDensity / wit * 600 * 8
                            val path = Path()
                            for (j in markStroke.list.indices) {
                                amark++
                                val point = markStroke.list[j]
                                val backup = baseBitmap!!.copy(Bitmap.Config.ARGB_4444, false)
                                if (j < markStroke.list.size - 1) {
                                    //这里mark笔的绘制有问题。可以优化
//                                    canvas.drawLine(getX(markStroke.list[j].x),
//                                            getY(markStroke.list[j].y),
//                                            getX(markStroke.list[j + 1].x),
//                                            getY(markStroke.list[j + 1].y), p)
                                    if (j == 0) {
                                        path.moveTo(getX(point.x), getY(point.y))
                                    } else {
                                        val lastPoint = markStroke.list[j - 1]
                                        path.quadTo(getX(lastPoint.x), getY(lastPoint.y), getX((lastPoint.x + point.x)) / 2f, getY((lastPoint.y + point.y)) / 2f)
                                    }
                                    canvas?.drawPath(path, p)
                                } else {
                                    val lastPoint = markStroke.list[j - 1]
                                    path.quadTo(getX(lastPoint.x), getY(lastPoint.y), getX((lastPoint.x + point.x)) / 2f, getY((lastPoint.y + point.y)) / 2f)
                                    canvas?.drawPath(path, p)
                                }
                                if (allPoint > 280) {
                                    val pagecount = 280 * div(markpoint.toDouble(), allPoint.toDouble(), 2)
                                    val z = div(markpoint.toDouble(), pagecount.toDouble(), 2)
                                    if (amark % z.toInt() == 0) {
//                                            bitmaplist = bitmapListOom(bitmaplist, ImageDispose.Bitmap2Bytes(baseBitmap.copy(Bitmap.Config.ARGB_4444, false)))
                                        bitmaplist = bitmapListOom(bitmaplist, ImageDispose.Bitmap2Bytes(baseBitmap))
                                    }
                                } else {
//                                        bitmaplist = bitmapListOom(bitmaplist, ImageDispose.Bitmap2Bytes(baseBitmap.copy(Bitmap.Config.ARGB_4444, false)))
                                    bitmaplist = bitmapListOom(bitmaplist, ImageDispose.Bitmap2Bytes(baseBitmap))
                                }
                                if (j < markStroke.list.size - 1) {
                                    canvas?.drawPaint(clearPaint)
                                    canvas?.drawBitmap(backup, 0f, 0f, null)
                                }
                            }
                        } else if (tempList[k].action == ACTION_STROKE) {
                            val pa = getPaint(context)
                            pa.color = PaletteColor.fromId(tempList[k].color).toColor()
                            pa.strokeWidth = context.screenDensity / wit * 600
                            for (j in 0 until tempList[k].list.size) {
                                astroke++
                                if (j != tempList[k].list.size - 1) {
                                    canvas?.drawLine(getX(tempList[k].list[j].x),
                                            getY(tempList[k].list[j].y),
                                            getX(tempList[k].list[j + 1].x),
                                            getY(tempList[k].list[j + 1].y), pa)
                                    if (allPoint > 280) {
                                        val pagecount = 280 * div(strokpoint.toDouble(), allPoint.toDouble(), 2)
                                        val z = div(strokpoint.toDouble(), pagecount.toDouble(), 2)
                                        if (astroke % z.toInt() == 0) {
//                                            bitmaplist = bitmapListOom(bitmaplist, ImageDispose.Bitmap2Bytes(baseBitmap.copy(Bitmap.Config.ARGB_4444, false)))
                                            bitmaplist = bitmapListOom(bitmaplist, ImageDispose.Bitmap2Bytes(baseBitmap))
                                        }
                                    } else {
//                                        bitmaplist = bitmapListOom(bitmaplist, ImageDispose.Bitmap2Bytes(baseBitmap.copy(Bitmap.Config.ARGB_4444, false)))
                                        bitmaplist = bitmapListOom(bitmaplist, ImageDispose.Bitmap2Bytes(baseBitmap))
                                    }
                                }
                            }
                        }
                        curIndex += tempList[k].list.size
                        progress = curIndex / allPoint * 50
                        circlePgBar.setmProgress(progress)
                        Log.i(TAG, "progress -> $progress")
                    }
                    for (x in 1..9) {
                        bitmaplist = bitmapListOom(bitmaplist, ImageDispose.Bitmap2Bytes(baseBitmap!!.copy(Bitmap.Config.ARGB_4444, false)))
                    }
                }
                val clear = Paint()
                clear.xfermode = PorterDuffXfermode(PorterDuff.Mode.CLEAR)
                canvas?.drawPaint(clear)
//                    clear.xfermode = PorterDuffXfermode(PorterDuff.Mode.SRC)
//                    canvas.drawColor(Color.WHITE)
                canvas?.drawBitmap(getWhiteBackBitmap(context), 0f, 0f, getPaint(context))
            }
            bitmapToVideo(bitmaplist, "temp", true)
            handler!!.post(runnfinishUi)
            getfinalpath(VideoPath!!)
            currBookId = -1
        }).start()
    }

    @SuppressLint("SimpleDateFormat")
    fun drawStrokesUntilProgress(strokeList: java.util.ArrayList<PenStroke>, context: Context, circlePgBar: CirclePgBar, wit: Int) {
        bgWidth = context.resources.displayMetrics.widthPixels
        this.circlePgBar = circlePgBar
        handler = Handler()
        mcontext = context
        this.width = 600
        isChange = true
//        val baseBitmap = getWhiteBackBitmap(context)

        //val baseBitmap = Bitmap.createBitmap(width, getBoardHeight(), Bitmap.Config.ARGB_4444)

        // val canvas = Canvas(baseBitmap)
//        var baseBitmap: Bitmap? = null
//        val canvas = Canvas()
        val clearPaint = Paint().apply {
            xfermode = PorterDuffXfermode(PorterDuff.Mode.CLEAR)
        }
        var dotCount = 0
        var curIndex: Double = 0.0

        progress = 0.0
        val pathlist: ArrayList<String> = mutableListOf<String>() as ArrayList<String>

        var countsize = 0
        Thread(Runnable {
            var baseBitmap: Bitmap? = null
            var canvas: Canvas = Canvas()
            circlePgBar.setmProgress(progress)
            val pageList = ArrayList<Int>()
            var pageMap: SparseArray<TempPageMap> = SparseArray()
            strokeList.forEach {
                if (pageMap.indexOfKey(it.bookId * 10000 + it.page) < 0) {
                    pageList.add(it.bookId * 10000 + it.page)
                    pageMap.append((it.bookId * 10000 + it.page), TempPageMap(it.page, it.bookId))
                }
                dotCount += it.list.size
            }
            pagesize = pageList.size
            // Log.e(TAG, "$pagesize")

            for (i in 0 until pagesize) {
                Log.i(TAG, "drawStrokesUntilProgress: ==$i")
                val page = pageMap[pageList[i]].page
                val bookId = pageMap[pageList[i]].bookId
                if (bookId != currBookId) {
                    currBookId = bookId
                    Log.i(TAG, "drawStrokesUntilProgress: bookId != currBookId=$currBookId")
                    bgHeight = PenT111.instance.calculatedHeight(currBookId, bgWidth)
                    currHeight = PenT111.instance.calculatedHeight(currBookId, this.width)
                    if (baseBitmap != null && !baseBitmap.isRecycled) {
                        baseBitmap.recycle()
                    }
                    baseBitmap = Bitmap.createBitmap(this.width, currHeight, Bitmap.Config.ARGB_4444)
                    canvas.setBitmap(baseBitmap)
                }
                val tempList: ArrayList<PenStroke> = mutableListOf<PenStroke>() as ArrayList<PenStroke>
                var bitmaplist: ArrayList<ByteArray> = mutableListOf<ByteArray>() as ArrayList<ByteArray>
                var n = 0
                var strokeCount = 0
                while (n < strokeList.size) {
                    if (strokeList[n].page == page && strokeList[n].bookId == bookId) {
                        tempList.add(strokeList[n])
                        strokeCount += strokeList[n].list.size
                        strokeList.removeAt(n)
                    } else {
                        n++
                    }
                }
                if (tempList.size == 0) {
                    Log.i(TAG, "drawStrokesUntilProgress: tempList.size == 0")
                    continue
                } else {
                    Log.i(TAG, "drawStrokesUntilProgress: tempList")
                    for (k in tempList.indices) {
                        if (tempList[k].action == ACTION_ERASER) {
                            val peraser = Paint()
                            peraser.color = Color.WHITE
                            for (j in 0 until tempList[k].list.size) {
                                val float = tempList[k].list[j].f * context.screenDensity / 2 / wit * 600
                                canvas?.drawCircle(getX(tempList[k].list[j].x), getY(tempList[k].list[j].y),
                                        float, peraser)
                                if (j == 0 || j == tempList[k].list.size - 1) {
                                    bitmaplist = bitmapListOom(bitmaplist, ImageDispose.Bitmap2Bytes(baseBitmap))
                                }
                            }
                        } else if (tempList[k].action == ACTION_MARK) {
                            val markStroke = tempList[k]
                            val p = getMarkPaint(context, PaletteColor.fromId(markStroke.color))
                            p.strokeWidth = context.screenDensity / wit * 600 * 8
                            val path = Path()
                            for (j in markStroke.list.indices) {
                                val point = markStroke.list[j]
                                val backup = baseBitmap!!.copy(Bitmap.Config.ARGB_4444, false)
                                if (j < markStroke.list.size - 1) {
                                    if (j == 0) {
                                        path.moveTo(getX(point.x), getY(point.y))
                                    } else {
                                        val lastPoint = markStroke.list[j - 1]
                                        path.quadTo(getX(lastPoint.x), getY(lastPoint.y), getX((lastPoint.x + point.x)) / 2f, getY((lastPoint.y + point.y)) / 2f)
                                    }
                                    canvas?.drawPath(path, p)
                                } else {
                                    val lastPoint = markStroke.list[j - 1]
                                    path.quadTo(getX(lastPoint.x), getY(lastPoint.y), getX((lastPoint.x + point.x)) / 2f, getY((lastPoint.y + point.y)) / 2f)
                                    canvas?.drawPath(path, p)
                                }
                                if (strokeCount > 300) {
                                    val a = strokeCount / 300
                                    if (countsize % a == 0) {
                                        bitmaplist = bitmapListOom(bitmaplist, ImageDispose.Bitmap2Bytes(baseBitmap))
                                    }
                                } else {
                                    bitmaplist = bitmapListOom(bitmaplist, ImageDispose.Bitmap2Bytes(baseBitmap))
                                }
                                if (j < markStroke.list.size - 1) {
                                    canvas.drawPaint(clearPaint)
                                    canvas.drawBitmap(backup, 0f, 0f, null)
                                }
                            }
                        } else if (tempList[k].action == ACTION_STROKE) {
                            val pa = getPaint(context)
                            pa.color = PaletteColor.fromId(tempList[k].color).toColor()
                            pa.strokeWidth = context.screenDensity / wit * 600
                            for (j in 0 until tempList[k].list.size) {
                                if (j != tempList[k].list.size - 1) {
                                    canvas.drawLine(getX(tempList[k].list[j].x),
                                            getY(tempList[k].list[j].y),
                                            getX(tempList[k].list[j + 1].x),
                                            getY(tempList[k].list[j + 1].y), pa)
                                    countsize++
                                    if (strokeCount > 250) {
                                        val a = strokeCount / 250
                                        if (countsize % a == 0) {
                                            bitmaplist = bitmapListOom(bitmaplist, ImageDispose.Bitmap2Bytes(baseBitmap))
                                        }
                                    } else {
                                        bitmaplist = bitmapListOom(bitmaplist, ImageDispose.Bitmap2Bytes(baseBitmap))
                                    }
                                }
                            }
                        }
                        curIndex += tempList[k].list.size
                        progress = curIndex / dotCount * 50
                        circlePgBar.setmProgress(progress)
                        Log.i(TAG, "progress -> $progress")
                    }
                    Log.i(TAG, "drawStrokesUntilProgress://////////0 ")
                    for (x in 1..9) {
                        bitmaplist = bitmapListOom(bitmaplist, ImageDispose.Bitmap2Bytes(baseBitmap))
                    }
                    Log.i(TAG, "drawStrokesUntilProgress://////////1")
                    val vpath: String? = bitmapToVideo(bitmaplist, i.toString(), false)
                    if (vpath != null) {
                        pathlist.add(vpath)
                    }
                    tempList.clear()
                    bitmaplist.clear()
                    val clear = Paint()
                    clear.xfermode = PorterDuffXfermode(PorterDuff.Mode.CLEAR)
                    canvas.drawPaint(clear)
                    canvas.drawBitmap(baseBitmap!!, 0f, 0f, getPaint(context))
                }
            }
            progress++
            if (progress > 100) {
                progress = 100.0
            }
            circlePgBar.setmProgress(progress)
            val sTimeFormat = SimpleDateFormat("yyyy-MM-dd-hh:mm:ss")
            val date = sTimeFormat.format(Date())
            Log.i(TAG, "drawStrokesUntilProgress: pathlist.size=${pageList.size}")
//            val composer = VideoComposer(pathlist, Environment.getExternalStorageDirectory().absolutePath + "/aiwirtetemp/ $date-temp..mp4")
            val composer = VideoComposer(pathlist, AIWriteApplication.instance.getExternalFilesDir("aiwirte")?.absolutePath + "/aiwirtetemp/ $date-temp..mp4")
            composer.joinVideo()
            handler!!.post(runnfinishUi)
            currBookId = -1
        }).start()
    }

    fun getfinalpath(string: String) {
        ShareVideoHelper.ChangeSuccess(string);
    }

    fun getBoardWidth(): Int = width
    fun getBoardHeight(): Int = (getBoardWidth().toFloat() / paperSize.width * paperSize.height).toInt()

    fun getX(x: Float): Float {
        Log.i(TAG, "getX0: width$width//bgHeight$bgWidth//currBookId$currBookId")
        if (currBookId == 4) {
            return x.toFloat() * getBoardWidth() / PaperSize.A5.width
        } else {
            return x.toFloat() * width / bgWidth
        }
    }

    fun getY(y: Float): Float {
        Log.i(TAG, "getX1: currHeight$currHeight//bgHeight$bgHeight//currBookId$currBookId")
        if (currBookId == 4) {
            return y.toFloat() * getBoardHeight() / PaperSize.A5.height
        } else {
            return y.toFloat() * currHeight / bgHeight
        }

    }

    fun getWhiteBackBitmap(context: Context): Bitmap {
        return newBitmap(getWhiteBitmap(), ViewToBitmapUtil.createVideoBottomBitmap(context))
    }

    private fun bitmapToVideo(bitmapArrayList: ArrayList<ByteArray>, name: String, isTen: Boolean): String? {
        Log.e(TAG, "bitmapToVideo: ----------")
        if (bitmapArrayList.isEmpty()) {
            Log.e(TAG, "bitmapToVideo: null")
            return null
        }
        VideoPath = null
        try {
            Log.e(TAG, "执行开始----------")
            val sTimeFormat = SimpleDateFormat("yyyy-MM-dd-hh:mm:ss")
            val date = sTimeFormat.format(Date())
            var se: SequenceEncoderMp4? = null
            val file = File(path)
            if (!file.exists())
                file.mkdir()
            val out = File(path, "$date-$name.mp4")
            if (out.exists())
                out.mkdir()
            if (isTen)
                se = SequenceEncoderMp4(out, 29)
            else
                se = SequenceEncoderMp4(out, 15)

            ImageDispose.saveBitmap(mcontext, ViewToBitmapUtil.createVideoBottomBitmap(mcontext), "bottom")
            ImageDispose.saveBitmap(mcontext, ImageDispose.compressImage(ViewToBitmapUtil.createVideoBottomBitmap(mcontext)), "bottom1")
            ImageDispose.saveBitmap(mcontext, ImageDispose.getimage(ImageDispose.SD_PATH + "bottom.jpg"), "bottom2")
            ImageDispose.saveBitmap(mcontext, ImageDispose.comp(ViewToBitmapUtil.createVideoBottomBitmap(mcontext)), "bottom3")
            val opt: BitmapFactory.Options = BitmapFactory.Options()
            var bottomBit = ViewToBitmapUtil.createVideoBottomBitmap(mcontext)
            bottomBit = resizeBitmap(bottomBit, 600, 60)
            for (i in 0 until bitmapArrayList.size) {
                se.encodeImage(newBitmap(changeBg(ImageDispose.getPicFromBytes(bitmapArrayList[i], opt)), bottomBit))
                Log.e(TAG, "视频-----$i")
                Log.e(TAG, "a" + div(i.toDouble(), bitmapArrayList.size.toDouble(), 2))
                Log.e(TAG, "b" + div(95.toDouble(), pagesize.toDouble(), 2))
                index = progress + div(i.toDouble(), bitmapArrayList.size.toDouble(), 2) * div(50.toDouble(), pagesize.toDouble(), 2)
                Log.e(TAG, "index -> $index")
                if (index > 100) {
                    index = 100.0
                }
                handler!!.post(runnableUi)
            }
            Log.e(TAG, "视频完成")
            se.finish()//TODO 页数太多进度条技算需要重新算，部分手机本地无法播放
            progress = progress + div(95.toDouble(), pagesize.toDouble(), 2)
            VideoPath = path + "$date-$name.mp4"
            return VideoPath
        } catch (e: IOException) {
            Log.e(TAG, "合成失败")
            return null
        }
        return VideoPath
    }

    fun bitmapListOom(oldlist: ArrayList<ByteArray>, bitmap: ByteArray): ArrayList<ByteArray> {
        //TODO bitmap或者可以先先存为byte[]
        if (oldlist.size > 300) {
//            val s = Random().nextInt(300) % (300 - 0 + 1) + 0
            val s = Random().nextInt(300)
            oldlist.removeAt(s)
        }
        oldlist.add(bitmap)
        return oldlist
    }

    fun getBitmapBac(): Bitmap? {
        val bottomHeight = mcontext!!.getResources().getDimension(R.dimen.dp40).toInt()
        val inflater = LayoutInflater.from(mcontext)
        val bottomView = inflater.inflate(R.layout.share_small_bottom, null)
        val bottomBitmap = loadBitmapFromView(bottomView, width, bottomHeight)
        return compressScale(bottomBitmap)
    }

    fun getWhiteBitmap(): Bitmap {
        val paint = Paint()
        paint.color = mcontext!!.resources.getColor(R.color.white)
        val bitmap = Bitmap.createBitmap(width, getBoardHeight(), Bitmap.Config.ARGB_4444)
        val canvas = Canvas(bitmap)
        canvas.drawRect(0f, 0f, bitmap.getWidth().toFloat(), bitmap.getHeight().toFloat(), paint)
        canvas.drawBitmap(bitmap, 0f, 0f, paint)
        return bitmap
    }

    // 构建Runnable对象，在runnable中更新界面
    var runnableUi: Runnable = Runnable {
        //更新界面
        circlePgBar.setmProgress(index)
    }
    var runnfinishUi: Runnable = Runnable {
        //更新界面
        circlePgBar.setmProgress(100.0)
        Handler().postDelayed({
            VideoProgressView.dismissLoadingView()
        }, 500)
    }

    /**
     * 提供（相对）精确的除法运算。当发生除不尽的情况时，由scale参数指
     * 定精度，以后的数字四舍五入。
     * @param v1 被除数
     * @param v2 除数
     * @param scale 表示表示需要精确到小数点以后几位。
     * @return 两个参数的商
     */
    fun div(v1: Double, v2: Double, scale: Int): Double {
        if (scale < 0) {
            throw IllegalArgumentException(
                    "The scale must be a positive integer or zero")
        }
        val b1 = BigDecimal(java.lang.Double.toString(v1))
        val b2 = BigDecimal(java.lang.Double.toString(v2))
        return b1.divide(b2, scale, BigDecimal.ROUND_HALF_UP).toDouble()
    }

    fun newBitmap(bmp1: Bitmap, bmp2: Bitmap): Bitmap {
        val retBmp: Bitmap
        val width = bmp1.width
        Log.i(TAG, "newBitmap: bmp1.height=${bmp1.height}")
        if (bmp2.width != width) {
            //以第一张图片的宽度为标准，对第二张图片进行缩放。
            val h2 = bmp2.height * width / bmp2.width
            retBmp = Bitmap.createBitmap(width, bmp1.height + h2, Bitmap.Config.ARGB_4444)
            val canvas = Canvas(retBmp)
            val newSizeBmp2 = resizeBitmap(bmp2, width, h2)
            canvas.drawBitmap(bmp1, 0f, 0f, null)
            canvas.drawBitmap(newSizeBmp2, 0f, bmp1.height.toFloat(), null)
        } else {
            //两张图片宽度相等，则直接拼接。
            retBmp = Bitmap.createBitmap(width, bmp1.height + bmp2.height, Bitmap.Config.ARGB_4444)
            val canvas = Canvas(retBmp)
            canvas.drawBitmap(bmp1, 0f, 0f, null)
            canvas.drawBitmap(bmp2, 0f, bmp1.height.toFloat(), null)
        }
        return retBmp
    }


    fun resizeBitmap(bitmap: Bitmap, newWidth: Int, newHeight: Int): Bitmap {
        val scaleWidth = newWidth.toFloat() / bitmap.width
        val scaleHeight = newHeight.toFloat() / bitmap.height
        val matrix = Matrix()
        matrix.postScale(scaleWidth, scaleHeight)
        return Bitmap.createBitmap(bitmap, 0, 0, bitmap.width, bitmap.height, matrix, true)
    }

    /**
     * 图片按比例大小压缩方法
     * @param image （根据Bitmap图片压缩）
     * @return
     */
    fun compressScale(image: Bitmap): Bitmap? {
        val baos = ByteArrayOutputStream()
        image.compress(Bitmap.CompressFormat.JPEG, 100, baos)
        // 判断如果图片大于1M,进行压缩避免在生成图片（BitmapFactory.decodeStream）时溢出
        if (baos.toByteArray().size / 1024 > 1024) {
            baos.reset()// 重置baos即清空baos
            image.compress(Bitmap.CompressFormat.JPEG, 80, baos)// 这里压缩50%，把压缩后的数据存放到baos中
        }
        var isBm = ByteArrayInputStream(baos.toByteArray())
        val newOpts = BitmapFactory.Options()
        // 开始读入图片，此时把options.inJustDecodeBounds 设回true了
        newOpts.inJustDecodeBounds = true
        var bitmap = BitmapFactory.decodeStream(isBm, null, newOpts)
        newOpts.inJustDecodeBounds = false
        val w = newOpts.outWidth
        val h = newOpts.outHeight
        Log.i(TAG, w.toString() + "---------------" + h)
        // 现在主流手机比较多是800*480分辨率，所以高和宽我们设置为
        // float hh = 800f;// 这里设置高度为800f
        // float ww = 480f;// 这里设置宽度为480f
        val hh = 40
        val ww = 200
        // 缩放比。由于是固定比例缩放，只用高或者宽其中一个数据进行计算即可
        var be = 1// be=1表示不缩放
        if (w > h && w > ww) {// 如果宽度大的话根据宽度固定大小缩放
            be = (newOpts.outWidth / ww).toInt()
        } else if (w < h && h > hh) { // 如果高度高的话根据高度固定大小缩放
            be = (newOpts.outHeight / hh).toInt()
        }
        if (be <= 0)
            be = 1
        newOpts.inSampleSize = be // 设置缩放比例
        // newOpts.inPreferredConfig = Config.RGB_565;//降低图片从ARGB888到RGB565
        // 重新读入图片，注意此时已经把options.inJustDecodeBounds 设回false了
        isBm = ByteArrayInputStream(baos.toByteArray())
        bitmap = BitmapFactory.decodeStream(isBm, null, newOpts)
        return bitmap;
    }

    private fun changeBg(bitmap: Bitmap): Bitmap {

        val bg = Bitmap.createBitmap(bitmap.width, bitmap.height, Bitmap.Config.ARGB_4444)
        val canvas = Canvas(bg)
        canvas.drawColor(Color.WHITE)
        canvas.drawBitmap(bitmap, 0f, 0f, null)
        return bg
    }

    fun onDestroy() {
        VideoPath = null
        isChange = false
    }

    class TempPageMap(var page: Int, var bookId: Int)
}